package com.link.play.fit.ai.utils

import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.HeartRateRecord
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.request.ReadRecordsRequest
import androidx.health.connect.client.time.TimeRangeFilter
import com.link.play.fit.ai.ext.d
import java.time.Instant
import java.time.LocalDate
import java.time.Period
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import kotlin.math.floor
import kotlin.math.roundToInt


object HealthUtils {
    private val PERMISSIONS =
        setOf(
            HealthPermission.getReadPermission(HeartRateRecord::class),
            HealthPermission.getWritePermission(HeartRateRecord::class),
            HealthPermission.getReadPermission(StepsRecord::class),
            HealthPermission.getWritePermission(StepsRecord::class)
        )

    fun isSupported(context: Context,autoInstall:Boolean=false): Boolean {
        try {
            val providerPackageName = "com.google.android.apps.healthdata"
            var availabilityStatus = 0
            kotlin.runCatching {
                availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName)
                if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
                    return false // sdk不可用
                }
            }

            if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
                if(autoInstall){
                // 安装healthconnect
                val uriString =
                    "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding"
                context.startActivity(
                    Intent(Intent.ACTION_VIEW).apply {
                        setPackage("com.android.vending")
                        data = Uri.parse(uriString)
                        putExtra("overlay", true)
                        putExtra("callerId", context.packageName)
                    }
                )}
                return false
            }
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false

    }


    // 获取当天步数（返回 Int）
    suspend fun getTodaySteps(healthConnectClient: HealthConnectClient): Long {
        if (!checkPermissionsAndRun(healthConnectClient)) {
            "Health Permission denied".d()
            return 0
        }
        // 2. 计算当天时间范围（00:00 - 当前时间）
        val today = LocalDate.now()
        val startTime = today.atStartOfDay().toInstant(ZoneOffset.UTC)
        val endTime = Instant.now()
        val request = ReadRecordsRequest(
            recordType = StepsRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )

        // 4. 执行查询并聚合结果
        return healthConnectClient.readRecords(request)
            .records
            .sumOf { it.count }
    }

    // 获取当天步数（返回 Int）
    suspend fun getLast7DaysSteps(
        startTime: Long = 0,
        healthConnectClient: HealthConnectClient
    ): Long {
        if (!checkPermissionsAndRun(healthConnectClient)) {
            "Permission denied".d()
            return 0
        }
        // 2. 计算当天时间范围（00:00 - 当前时间）
        val today = LocalDate.now()
//        val startTime = today.atStartOfDay().toInstant(ZoneOffset.UTC)
        val cuTime = Instant.now()
        " cuTime ${cuTime}".d()
//        val currentTime = Instant.ofEpochSecond(1616623980L)
        val currentTime = Instant.ofEpochMilli(startTime)

        // 获取当前时间
//        val currentTime = Instant.now()
        // 计算7天前的时间
        val sevenDaysAgo = currentTime.minus(Period.ofDays(7))

        val (startTime, endTime) = get7DaysTimeRange()

        val request = ReadRecordsRequest(
            recordType = StepsRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
        // 4. 执行查询
        val response = healthConnectClient.readRecords(request)
        "response ${response.records.size}".d()
        // 4. 执行查询并聚合结果
        return response
            .records
            .sumOf {
                "records $it".d()
                it.count
            }
    }


    // 计算最近7天时间范围（UTC时间戳）
    private fun get7DaysTimeRange(): Pair<Instant, Instant> {
        val endTime = Instant.now()
        val startTime = endTime.minusSeconds(7 * 24 * 3600) // 7天前
        return Pair(startTime, endTime)
    }

    suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient): Boolean {
        val granted = healthConnectClient.permissionController.getGrantedPermissions()
        return granted.containsAll(PERMISSIONS)
    }

    //根据步数转换成卡路里
    fun calculateStepCalorieBurn(steps: Long, weight: Float, height: Double): Int {
        return ((((((((height / 100) * 0.414) * steps) / 1.34) * 3.5) * 3.5) * weight) / 12000).toInt()
    }

    fun timeToISOFormatter(time: Long): String {
        // 将时间戳转换为 Instant
        val instant = Instant.ofEpochMilli(time)
        // 定义 ISO 8601 格式的 DateTimeFormatter
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'")
            .withZone(ZoneId.of("UTC"))
        // 格式化时间戳
        val formattedTime = formatter.format(instant)

        return formattedTime
    }

    /**
     * 计算 BMR
     * weight 体重kg
     * height 身高cm
     * age 年纪
     * sex 性别
     */
    fun calculateDailyCalorieExpenditure(weight: Float, height: Int, age: Int = 20, sex: Int = 1): Int {
        var value = 0.0
        when (sex) {
            1 -> {  //男性
                value = weight * 13.397 + height * 4.799 - age * 13.397 + 88.362
            }

            2 -> {  //女性
                value = weight * 9.247 + height * 3.098 - age * 4.33 + 447.593
            }
        }
        return value.toInt()
    }

    /**
     * 计算蛋白质
     */
    fun calculateProtein(sex: Int, weight: Int, calories: Int, bmr: Int): Double {
        var value = 0.0
        when (sex) {
            1 -> {  //男性
                value = weight * 1.0 + (calories - bmr) * 0.05
            }

            2 -> {  //女性
                value = weight * 0.75 + (calories - bmr) * 0.05
            }
        }
        return value
    }

    /**
     * 计算碳水化合物
     */
    fun calculateCarbs(calories: Int, protein: Int, fat: Int): Int {
        return (calories - (protein * 4) - (fat * 9)) / 4
    }

    /**
     * 计算脂肪
     */
    fun calculateFat(calories: Int): Double {
        return (calories * 0.25) / 9
    }

    /**
     * 获取运动量
     * low 低运动量
     * medium 中等
     * high 高等
     */
    fun amountOfexercise(bmr: Double, type: Int): Double {
        var value = 0.0
        when (type) {
            1 -> {  //low
                value = bmr * 1.0
            }

            2 -> {  //medium
                value = bmr * 1.2
            }

            3 -> {  //high
                value = bmr * 1.375
            }
        }
        return value
    }

    /**
     * 英尺转换cm
     */
    fun feetInchToCm(feet: Int, inch: Int): Int {
        require(feet >= 0 && inch in 0..11) { }
        return (feet * 30.48 + inch * 2.54).roundToInt()
    }

    /**
     * cm转换英尺
     */
    fun cmToFeetInch(cm: Int): Pair<Int, Int> {
        require(cm >= 0) { }
        val totalInches = cm / 2.54
        val feet = (totalInches / 12).toInt()
        val inch = (totalInches % 12).roundToInt()
        return Pair(feet, inch)
    }

    /** kg → lbs */
    fun convertKgToLbs(kg: Int): Int {
        return (kg * 2.20462).roundToInt()
    }

    /** lbs → kg */
    fun convertLbsToKg(lbs: Int): Int {
        return (lbs * 0.453592).roundToInt()
    }

    /** lbs → kg */
    fun convertLbsToKgToF(lbs: Float): Float {
        return ((lbs * 0.453592).toFloat())
    }


    fun convertCmToFtIn(cm: Double): Pair<Int, Int> {
        // 1 英尺 = 30.48 厘米
        val feet = floor(cm / 30.48).toInt()
        // 剩余的厘米转换为英寸，1 英寸 = 2.54 厘米
        val inches = ((cm - feet * 30.48) / 2.54).roundToInt() // 四舍五入到最接近的整数
        return Pair(feet, inches)
    }

    fun covertFtInToCm(feet: Int, inches: Int): Int {
        // 1 英尺 = 30.48 厘米
        val feetToCm = feet * 30.48
        // 1 英寸 = 2.54 厘米
        val inchesToCm = inches * 2.54
        // 总厘米数
        val totalCm = feetToCm + inchesToCm
        // 返回结果，四舍五入到最接近的整数
        return totalCm.roundToInt()
    }

}